package com.hcloud.gateway.webhandler;

import com.hcloud.gateway.captcha.PngCaptcha;
import com.wf.captcha.Captcha;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.hcloud.common.redis.util.RedisUtil;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.HandlerFunction;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * @Auther hepangui
 * 直接处理验证码请求，返回图片
 * @Date 2018/10/27
 */
@Slf4j
@Component
@AllArgsConstructor
public class ImageCodeWebHandler  implements HandlerFunction<ServerResponse> {

    private static final int width = 120;
    private static final int height = 40;
    private static final int length = 4;
    private static final String fontName= "Verdana";
    private static final int fontSize = 32;

    private static final String COKE_KEY_PREFIX = "CODE_";
    private static final long CODE_EXPIRE_TIME = 300; //5分钟失效

    /**
     * 前端获取code时，加上参数uuid，后台生成验证码并与uuid对应，放入redis中
     * 登录时，通过uuid获取code进行比对。
     * @param serverRequest
     * @return
     */
    @Override
    public Mono<ServerResponse> handle(ServerRequest serverRequest) {
        // 图片输出流
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        String uuid = serverRequest.queryParam("uuid").get();

        PngCaptcha pngCaptcha = new PngCaptcha(width, height, length);
        // 设置字体
        pngCaptcha.setFont(new Font(fontName, Font.PLAIN, fontSize));
        // 设置类型，纯数字、纯字母、字母数字混合
        pngCaptcha.setCharType(Captcha.TYPE_ONLY_CHAR);
        BufferedImage pngImage = pngCaptcha.getPngImage();
        //获取生成的验证码值
        String text = pngCaptcha.text();
        log.info("验证码："+text);
        RedisUtil.set(COKE_KEY_PREFIX+uuid,text,CODE_EXPIRE_TIME);
        try {
            ImageIO.write(pngImage, "png", os);
        } catch (IOException e) {
            log.error("验证码生成失败", e);
            return Mono.error(e);
        }
        return ServerResponse
                .status(HttpStatus.OK)
                .contentType(MediaType.IMAGE_PNG)
                .body(BodyInserters.fromResource(new ByteArrayResource(os.toByteArray())));
    }
}
